//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using System;
using System.ComponentModel;
using System.Linq;
using System.Transactions;
using P2.Cuberry.Framework.BOLBase;
using P2.Cuberry.Framework.Helper;
using P2.Cuberry.Framework.Helper.Configuration;
using P2.Cuberry.Framework.Security;
using P2.Cuberry.Modules.Clinicom.CCPatientVisit.DAL;


namespace P2.Cuberry.Modules.Clinicom.CCPatientVisit.BusinessEntities
{
    public class CCPatientVisit : BizObject, INotifyPropertyChanged
    {

        #region Members

        //++KeyID
        int _visitID = -1;
        public int VisitID
        {
            get { return _visitID; }
            protected set
            {
                if (_visitID != value)
                {
                    _visitID = value;
                }
            }
        }

        //Add++
        DateTime? _openingTime = DateTime.Now;
        public DateTime? OpeningTime
        {
            get { return _openingTime; }
            set
            {
                if (value != _openingTime)
                {
                    _openingTime = value;
                    Modified = true;
                }
            }
        }

        DateTime? _closingTime = DateTime.Now;
        public DateTime? ClosingTime
        {
            get { return _closingTime; }
            set
            {
                if (value != _closingTime)
                {
                    _closingTime = value;
                    Modified = true;
                }
            }
        }

        string _leavingStatus = String.Empty;
        public string LeavingStatus
        {
            get { return _leavingStatus; }
            set
            {
                if (value != _leavingStatus)
                {
                    _leavingStatus = value;
                    Modified = true;
                }
            }
        }

        string _closedBy = String.Empty;
        public string ClosedBy
        {
            get { return _closedBy; }
            set
            {
                if (value != _closedBy)
                {
                    _closedBy = value;
                    Modified = true;
                }
            }
        }

        string _diagnosis = String.Empty;
        public string Diagnosis
        {
            get { return _diagnosis; }
            set
            {
                if (value != _diagnosis)
                {
                    _diagnosis = value;
                    Modified = true;
                }
            }
        }

        string _therapyDuration = String.Empty;
        public string TherapyDuration
        {
            get { return _therapyDuration; }
            set
            {
                if (value != _therapyDuration)
                {
                    _therapyDuration = value;
                    Modified = true;
                }
            }
        }

        string _note = String.Empty;
        public string Note
        {
            get { return _note; }
            set
            {
                if (value != _note)
                {
                    _note = value;
                    Modified = true;
                }
            }
        }




        //DDL++
        int _patientID;
        public int PatientID
        {
            get { return _patientID; }
            set
            {
                if (value != _patientID)
                    _patientID = value;
                Modified = true;
            }
        }

        public CCPatient CCPatient
        {
            get
            { return BusinessEntities.CCPatient.GetItem(this.PatientID); }
        }
        int? _bedID = null;
        public int? BedID
        {
            get { return _bedID; }
            set
            {
                if (value != _bedID)
                    _bedID = value;
                Modified = true;
            }
        }

        public CCBed CCBed
        {
            get
            { return BusinessEntities.CCBed.GetItem(this.BedID.GetValueOrDefault(-1)); }
        }
        int? _visitCategoryID = null;
        public int? VisitCategoryID
        {
            get { return _visitCategoryID; }
            set
            {
                if (value != _visitCategoryID)
                    _visitCategoryID = value;
                Modified = true;
            }
        }

        public CCVisitCategory CCVisitCategory
        {
            get
            { return BusinessEntities.CCVisitCategory.GetItem(this.VisitCategoryID.GetValueOrDefault(-1)); }
        }
        int? _contractor = null;
        public int? Contractor
        {
            get { return _contractor; }
            set
            {
                if (value != _contractor)
                    _contractor = value;
                Modified = true;
            }
        }

        public CROrganisation CROrganisation
        {
            get
            { return BusinessEntities.CROrganisation.GetItem(this.Contractor.GetValueOrDefault(-1)); }
        }



        #endregion


        #region Computed Properties
        //DDL++
        public string CCPatientCur
        {
            get
            {
                if (this.CCPatient != null)
                    return this.CCPatient.CCPatientCur;
                else
                    return "";
            }
        }

        public string CCBedCur
        {
            get
            {
                if (this.CCBed != null)
                    return this.CCBed.CCBedCur;
                else
                    return "";
            }
        }

        public string CCVisitCategoryCur
        {
            get
            {
                if (this.CCVisitCategory != null)
                    return this.CCVisitCategory.CCVisitCategoryCur;
                else
                    return "";
            }
        }

        public string CROrganisationCur
        {
            get
            {
                if (this.CROrganisation != null)
                    return this.CROrganisation.CROrganisationCur;
                else
                    return "";
            }
        }



        #endregion


        #region Constructors

        public CCPatientVisit()
        {
            Modified = false;
        }


        public CCPatientVisit(int keyVisitID)
        {
            this._visitID = keyVisitID;
            FillMyObject();
            Modified = false;
        }


        public CCPatientVisit(DAL.CCPatientVisit ccPatientVisit)
        {
            Load(ccPatientVisit);
        }

        #endregion


        #region Read Operations

        //load an existing Instance
        public void Load(int keyVisitID)
        {
            VisitID = keyVisitID;
            if (keyVisitID >= 0)
            {
                FillMyObject();
            }
            else
            {
                Load(null);
            }
            Modified = false;
        }


        //Add++ //DDL++
        public void Load(DAL.CCPatientVisit sourceEntity)
        {
            if (sourceEntity != null)
            {
                this.VisitID = sourceEntity.VisitID;

                this.OpeningTime = sourceEntity.OpeningTime;
                this.ClosingTime = sourceEntity.ClosingTime;
                this.LeavingStatus = sourceEntity.LeavingStatus;
                this.ClosedBy = sourceEntity.ClosedBy;
                this.Diagnosis = sourceEntity.Diagnosis;
                this.TherapyDuration = sourceEntity.TherapyDuration;
                this.Note = sourceEntity.Note;

                this.PatientID = sourceEntity.PatientID;
                this.BedID = sourceEntity.BedID;
                this.VisitCategoryID = sourceEntity.VisitCategoryID;
                this.Contractor = sourceEntity.Contractor;

                //Default Fields                
                this.CreatedBy = sourceEntity.CreatedBy;
                this.CreatedOn = sourceEntity.CreatedOn;
                this.EditedBy = sourceEntity.EditedBy;
                this.EditedOn = sourceEntity.EditedOn;
                this.Timestamp = sourceEntity.TStamp;
                this.StatusID = sourceEntity.StatusID.GetValueOrDefault(P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus.GetInitialStatus(this.EntityName).StatusID);
            }
            else
            {
                this.VisitID = -1;

                this.OpeningTime = null;
                this.ClosingTime = null;
                this.LeavingStatus = String.Empty;
                this.ClosedBy = String.Empty;
                this.Diagnosis = String.Empty;
                this.TherapyDuration = String.Empty;
                this.Note = String.Empty;

                this.PatientID = -1;
                this.BedID = null;
                this.VisitCategoryID = null;
                this.Contractor = null;

                //Default Fields
                this.CreatedBy = String.Empty;
                this.EditedBy = String.Empty;
                P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus initStatus = P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus.GetInitialStatus(this.EntityName);
                this.StatusID = initStatus.StatusID;
            }
            Modified = false;
        }


        internal P2TransactionMessage FillMyObject()
        {
            P2TransactionMessage tMsg = new P2TransactionMessage();
            if (this._visitID < 0)
            {
                Load(this._visitID);
                return tMsg;
            }

            try
            {
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (CCPatientVisitDataContext db = new CCPatientVisitDataContext(connectionString))
                {
                    var xElements = from xElement in db.CCPatientVisit
                                    where xElement.VisitID == this._visitID
                                    select xElement;

                    foreach (var xElementx in xElements)
                    {
                        Load(xElementx);
                    }
                }

                tMsg.TransactionStatus = "green";
                tMsg.MessageText = "TMsg_FillMyObjectSuceeded";
            }
            catch (Exception ex)
            {
                tMsg.TransactionStatus = "red";
                tMsg.MessageText = "Error_Error";
                tMsg.MessageFreeText = ex.Message;
                P2ExceptionHandler.LogException(ex, this);
            }

            this.MessageStack.Add(tMsg);
            return tMsg;

        }
        #endregion


        #region Update Operations

        //Add++
        public P2MessageStack InsertAndUpdate(P2MessageStack MessageStack, bool checkDoublicate)
        {
            MessageStack.AddRange(this.Validator.Validate(this));

            try
            {
                if (MessageStack.StatusMessage.MessageStatus == P2ValidationStatus.green || MessageStack.StatusMessage.MessageStatus == P2ValidationStatus.white || (MessageStack.StatusMessage.MessageStatus == P2ValidationStatus.yellow && P2Validator.YellowErrorDialog.AskSave(MessageStack)))
                {
                    MessageStack.Clear();
                    string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);

                    using (DAL.CCPatientVisitDataContext db = new DAL.CCPatientVisitDataContext(connectionString))
                    {
                        using (TransactionScope ts = new TransactionScope())
                        {
                            //Add++ //DDL++ //--> Set it to starting status.
                            if (this.StatusID == -1) this.StatusID = 7003;

                            if (string.IsNullOrEmpty(this.CreatedBy)) this.CreatedBy = User.Current.UserID;
                            this.EditedBy = User.Current.UserID;

                            DAL.CCPatientVisit editedItem;
                            if (this.VisitID < 0)
                            {
                                editedItem = new DAL.CCPatientVisit()
                                {
                                    OpeningTime = this.OpeningTime,
                                    ClosingTime = this.ClosingTime,
                                    LeavingStatus = this.LeavingStatus,
                                    ClosedBy = this.ClosedBy,
                                    Diagnosis = this.Diagnosis,
                                    TherapyDuration = this.TherapyDuration,
                                    Note = this.Note,
                                    PatientID = this.PatientID,
                                    BedID = this.BedID,
                                    VisitCategoryID = this.VisitCategoryID,
                                    Contractor = this.Contractor,

                                    //Default Fields
                                    CreatedBy = User.Current.UserID,
                                    CreatedOn = DateTime.Now,
                                    EditedBy = User.Current.UserID,
                                    EditedOn = DateTime.Now,
                                    StatusID = this.StatusID
                                };
                                db.AddToCCPatientVisit(editedItem);
                            }
                            else
                            {
                                editedItem = (from xItem in db.CCPatientVisit
                                              where xItem.VisitID == this.VisitID
                                              select xItem).First();
                                if (editedItem.TStamp == this.Timestamp)
                                {
                                    //Add++ //DDL++
                                    editedItem.OpeningTime = this.OpeningTime;
                                    editedItem.ClosingTime = this.ClosingTime;
                                    editedItem.LeavingStatus = this.LeavingStatus;
                                    editedItem.ClosedBy = this.ClosedBy;
                                    editedItem.Diagnosis = this.Diagnosis;
                                    editedItem.TherapyDuration = this.TherapyDuration;
                                    editedItem.Note = this.Note;

                                    editedItem.PatientID = this.PatientID;
                                    editedItem.BedID = this.BedID;
                                    editedItem.VisitCategoryID = this.VisitCategoryID;
                                    editedItem.Contractor = this.Contractor;

                                    //Default Fields
                                    editedItem.EditedBy = User.Current.UserID;
                                    editedItem.EditedOn = DateTime.Now;
                                    editedItem.StatusID = this.StatusID;

                                    //track changes!
                                    this.SaveChangeLog(this.VisitID);
                                }
                                else
                                {
                                    MessageStack.Add(new P2TransactionMessage("red", P2Translator.GetResource("TMsg_AccountNotUpdated"))); //--> rename it
                                }
                            }
                            if (MessageStack.StatusMessage.MessageStatus != P2ValidationStatus.red)
                            {
                                db.SaveChanges();
                                ts.Complete();
                                if (this.VisitID < 0)
                                {
                                    MessageStack.Add(new P2TransactionMessage("green", P2Translator.GetResource("TMsg_PatientVisitAdded")));
                                    this.VisitID = editedItem.VisitID;
                                }
                                else
                                    MessageStack.Add(new P2TransactionMessage("green", P2Translator.GetResource("TMsg_PatientVisitUpdated")));
                            }
                        }
                    }

                    FillMyObject();
                    Modified = false;
                }
            }
            catch (Exception ex)
            {
                MessageStack.Add(new P2TransactionMessage("red", P2Translator.GetResource("Error_Error")));
                P2ExceptionHandler.LogException(ex, this);
            }
            return MessageStack;
        }

        #endregion


        #region Property Changed

        public event PropertyChangedEventHandler PropertyChanged;


        private void OnPropertyChanged(string propertyName)
        {
            Modified = true;
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null) Handler(this, new PropertyChangedEventArgs(propertyName));
        }

        //Add++ //DDL++
        public void OnAllPropertiesChanged()
        {
            OnPropertyChanged("VisitID");

            OnPropertyChanged("OpeningTime");
            OnPropertyChanged("ClosingTime");
            OnPropertyChanged("LeavingStatus");
            OnPropertyChanged("ClosedBy");
            OnPropertyChanged("Diagnosis");
            OnPropertyChanged("TherapyDuration");
            OnPropertyChanged("Note");


            OnPropertyChanged("PatientID");
            OnPropertyChanged("BedID");
            OnPropertyChanged("VisitCategoryID");
            OnPropertyChanged("Contractor");


            //Standard Fields
            OnPropertyChanged("StatusName");
            OnPropertyChanged("StatusID");
        }

        #endregion


        #region Validator

        public override P2Validator Validator
        {
            get
            {
                if (_validator == null)
                    _validator = new P2Validator(Properties.Settings.Default.ModuleName, this.EntityName, "VisitID", this);
                return _validator;
            }
        }

        #endregion


    }
}

